/**
 * Copyright 2008 Mathias Doenitz, http://lis.to/
 *
 * This file is part of the lis.to java desktop client. The lis.to java desktop client is free software: you can
 * redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * The lis.to java desktop client is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with the lis.to java desktop client.
 * If not, see http://www.gnu.org/licenses/
 */

package listo.client.actions;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import listo.client.ContextManager;
import listo.client.model.Context;
import listo.client.model.Tasks;
import listo.client.model.operations.Operation;
import listo.client.taskfilters.TaskFilter;
import listo.client.taskfilters.TrashFilter;
import listo.client.tasklists.TaskList;
import listo.client.tasklists.TaskListManager;
import listo.client.viewlists.*;

import javax.swing.*;

@Singleton
public class ActionManager implements ContextManager.ContextChangedListener, ViewListManager.ViewSelectionListener,
        TaskListManager.TaskSelectionListener {

    private final Actions actions;
    private final FolderViewList folderViewList;

    private View[] selectedViews;

    @Inject
    public ActionManager(ContextManager contextManager, Actions actions, ViewListManager viewListManager,
                         FolderViewList folderViewList, TaskListManager taskListManager, TrashFilter trashFilter) {
        this.actions = actions;
        this.folderViewList = folderViewList;

        contextManager.addContextChangedListener(this);
        viewListManager.addViewListSelectionListener(this);
        taskListManager.addTaskSelectionListener(this);

        trashFilter.addFilterListener(new TaskFilter.Listener() {
            public void tasksChanged(Object updateObject) {
                Tasks tasks = (Tasks) updateObject;
                ActionManager.this.actions.emptyTrashAction.setEnabled(!tasks.isEmpty());
            }
        });
    }

    /**
     * Called by the ContextManager on a context change.
     * CAUTION: This method is being called from the context thread.
     *
     * @param context the current Context
     * @param undoOp  the current undoOp
     * @param redoOp  the current redoOp
     */
    public void currentContextChanged(Context context, final Operation undoOp, final Operation redoOp) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                actions.redoAction.setEnabled(redoOp != null);
                if (redoOp != null) actions.redoAction.updateDescription(redoOp);
                actions.undoAction.setEnabled(undoOp != null);
                if (undoOp != null) actions.undoAction.updateDescription(undoOp);
            }
        });
    }

    public void viewSelectionChanged(View[] selectedViews) {
        this.selectedViews = selectedViews;
        int[] selectedIndices = folderViewList.getSelectedIndices();
        actions.deleteFoldersAction.setEnabled(selectedIndices.length > 0);
        actions.editFolderAction.setEnabled(selectedIndices.length == 1);
    }

    public void taskSelectionChanged(TaskList taskList, Tasks selectedTasks) {
        boolean isNotTrashView = selectedViews == null || selectedViews.length == 0 ||
                !(selectedViews[0] instanceof TrashView);
        actions.toggleTasksCompletedAction.setEnabled(isNotTrashView && !selectedTasks.isEmpty());
        actions.editTaskAction.setEnabled(isNotTrashView && selectedTasks.size() == 1);
        actions.deleteTasksAction.setEnabled(isNotTrashView && !selectedTasks.isEmpty());
        actions.detachCurrentFoldersAction.setEnabled(selectedViews != null && selectedViews.length > 0 &&
                (selectedViews[0] instanceof FolderView) && !selectedTasks.isEmpty() &&
                selectedTasks.allHaveAtLeastTwoFolders());
    }
}
